package cqrtplm.service.impl;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hustcad.plm.basic.util.TyplmEntityBaseUtil;
import com.hustcad.plm.pdm.classification.model.dto.TyplmClassificationEntityDTO;
import com.hustcad.plm.pdm.classification.model.dto.TyplmClassificationQueryTreeDTO;
import com.hustcad.plm.pdm.classification.model.vo.TyplmClassificationEntityTreeVO;
import com.hustcad.plm.pdm.classification.service.TyplmClassificationService;
import com.hustcad.plm.pdm.common.model.dto.search.SearchConditionDTO;
import com.hustcad.plm.pdm.common.model.vo.search.ResultEntityVO;
import com.hustcad.plm.pdm.common.service.search.TyplmClassifySearchService;
import com.hustcad.plm.pdm.common.util.CommonUtil;
import com.hustcad.plm.pdm.enumeration.service.TyplmEnumerationService;
import com.hustcad.plm.pdm.iba.service.TyplmAttributeValueService;
import com.hustcad.plm.pdm.projectshared.mapper.project.TyplmProjectMapper;
import com.hustcad.plm.pdm.projectshared.service.project.TyplmProjectService;
import com.ty.basic.constant.TableTypeConstrant;
import com.ty.basic.entity.project.ProjectDO;
import com.ty.basic.service.snow.SnowflakeIdComponent;
import com.ty.basic.session.TyAccountContext;
import com.ty.basic.vo.AttributeVO;
import cqrtplm.constant.RTErrorCodeEnum;
import cqrtplm.constant.RTPlmConstant;
import cqrtplm.dto.ProductSpectrumDTO;
import cqrtplm.entity.ProjectDevOrderDO;
import cqrtplm.mapper.ProjectDevOrderMapper;
import cqrtplm.service.DevOrderService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author：lotus
 * @DATE: 2025/7/7 14:59
 */

@Slf4j
@Service
@Transactional
public class DevOrderServiceImpl implements DevOrderService {


    @Resource
    private ProjectDevOrderMapper projectDevOrderMapper;
    @Resource
    private TyplmEnumerationService typlmEnumerationService;
    @Resource
    private TyplmClassificationService typlmClassificationService;
    @Resource
    private TyplmClassifySearchService typlmClassifySearchService;
    @Resource
    private TyplmAttributeValueService typlmAttributeValueService;
    @Resource
    private SnowflakeIdComponent snowflakeIdComponent;
    @Resource
    private TyplmProjectService typlmProjectService;
    @Autowired
    @Lazy
    private TyplmProjectMapper typlmProjectMapper;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insert(ProjectDevOrderDO devOrderDO) {
        ProjectDevOrderDO proDevOrderDO = projectDevOrderMapper.queryLastedCreateProDevCode(devOrderDO.getDevOrderNumber(),devOrderDO.getDevCategory());
        String flowCode = "";
        if(ObjectUtil.isEmpty(proDevOrderDO)){
            flowCode = "01";
        } else {
            String serial = proDevOrderDO.getProjectCode().substring(5, 7);
            try {
                int value = Integer.parseInt(serial);
                value = (value + 1) % 100; // 自动处理进位
                flowCode = String.format("%02d", value);
            } catch (NumberFormatException e) {
                throw RTErrorCodeEnum.GENERATE_CODE_ERROR.getException("无效的数字格式: " + serial);
            }
        }
        ProjectDO projectDO = typlmProjectService.queryProjectByNameIgnore(devOrderDO.getProjectName());
        if (projectDO != null) {
            throw RTErrorCodeEnum.PROJECT_DEV_ORDER.getException("项目已存在，请重新输入项目名称。");
        } else {
            List<ProjectDevOrderDO> devOrderDOS = projectDevOrderMapper.queryProjectDevOrderByName(
                    devOrderDO.getProjectName());
            if (!CollUtil.isEmpty(devOrderDOS)) {
                throw RTErrorCodeEnum.PROJECT_DEV_ORDER.getException("项目名称重复，请重新输入");
            }
        }

        String projectCode = devOrderDO.getDevOrderNumber()+"-"+devOrderDO.getDevCategory() + flowCode;
        devOrderDO.setProjectCode(projectCode);
        devOrderDO.setCreateBy(TyAccountContext.getUser().getFullname());
        devOrderDO.setOid(snowflakeIdComponent.getInstance().nextId());
        //devOrderDO.setUpdateBy(TyAccountContext.getUser().getFullname());
        TyplmEntityBaseUtil.fillCommonFieldForCreate(devOrderDO);
        devOrderDO.setUpdatestamp(null);
        projectDevOrderMapper.insert(devOrderDO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(String oid) {
        ProjectDevOrderDO projectDevOrderDO = projectDevOrderMapper.selectByPrimaryKey(oid);
        String devOrderNumber = projectDevOrderDO.getProjectCode();
        if(StringUtils.isBlank(devOrderNumber) || StringUtils.isEmpty(devOrderNumber)){
            projectDevOrderMapper.deleteByPrimaryKey(oid);
        }else {
            List<String> projectNumbers = projectDevOrderMapper.selectProjectNumberByKey(devOrderNumber);
            if (log.isDebugEnabled()){
                projectNumbers.stream().forEach(System.out::println);
            }
            if(CollUtil.isEmpty(projectNumbers)){
                projectDevOrderMapper.deleteByPrimaryKey(oid);
            } else {
                throw RTErrorCodeEnum.CUSTOM_EXCEPTION.getException("当前行已被项目:" + String.join(",", projectNumbers) + "关联,不能删除");
            }
        }
    }

    @Override
    public List<ProjectDevOrderDO> queryProjectDevOrderByNumber(String number) {
        return projectDevOrderMapper.queryProjectDevOrderByNumber(number);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(ProjectDevOrderDO devOrderDO) {
        // 修改开发令时项目已存在，项目名称不允许修改。
        //ProjectDO projectDO = typlmProjectService.queryProjectByNameIgnore(devOrderDO.getProjectName());
        List<ProjectDO> projectDOS = typlmProjectMapper.queryProjectByNameIgnore(devOrderDO.getProjectName());
        if (projectDOS.size() > 1) {
            throw RTErrorCodeEnum.PROJECT_DEV_ORDER.getException("项目已存在，项目名称不允许修改。");
        } else {
            List<ProjectDevOrderDO> devOrderDOS = projectDevOrderMapper.queryProjectDevOrderByName(
                    devOrderDO.getProjectName());
            if (devOrderDOS.size() > 1) {
                throw RTErrorCodeEnum.PROJECT_DEV_ORDER.getException("项目名称重复，请重新输入。");
            }
        }
        devOrderDO.setUpdateBy(TyAccountContext.getUser().getFullname());
        TyplmEntityBaseUtil.fillCommonFieldForUpdate(devOrderDO);
        projectDevOrderMapper.updateByPrimaryKey(devOrderDO);
    }

    @Override
    public List<ProjectDevOrderDO> queryProjectDevCodeByName(String name) {
        if("TJ".equals(name) || StringUtils.isEmpty(name) || StringUtils.isBlank(name)){
            return projectDevOrderMapper.queryAllDevOrder(null);
        }else if(name.length()==1){
            return projectDevOrderMapper.queryDevCodeByProduceLine(name);
        } else {
            return projectDevOrderMapper.queryDevCodeByDevCode(name);
        }
    }

    @Override
    public ProjectDevOrderDO queryProjectDevOrderProjectCode(String projectCode) {

        return  projectDevOrderMapper.queryProjectDevOrderProjectCode(projectCode);

    }

    @Override
    public PageInfo<ProjectDevOrderDO>  queryAllDevOrder(String projectCode,int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<ProjectDevOrderDO> projectDevOrderDOList = projectDevOrderMapper.queryAllDevOrder(projectCode);
        return new PageInfo<>(projectDevOrderDOList);
    }

    @Override
    public Map<String, Map<String, String>> getAttr(List<String> fields) {
        return typlmEnumerationService.getEnumItemsMap(fields);
    }

    @Override
    public ProductSpectrumDTO getAllProductSpectrum() {
        TyplmClassificationEntityDTO entityDTO = typlmClassificationService.queryClassificationByTypeAndName("", "ProductSpecification");
        TyplmClassificationQueryTreeDTO queryTreeDTO = new TyplmClassificationQueryTreeDTO();
        queryTreeDTO.setTypeOid(new BigInteger(entityDTO.getRootid()));
        queryTreeDTO.setOid(new BigInteger(entityDTO.getId()));
        TyplmClassificationEntityTreeVO parentClassTreeVO = this.typlmClassificationService.queryClassificationTree(queryTreeDTO).get(0);
        List<String> ibaAttr = Arrays.asList("productType", "devCode", "ProductSeries");
        ProductSpectrumDTO parentProductSpectrumDTO = new ProductSpectrumDTO();
        // 设置根节点的分类OID
        parentProductSpectrumDTO.setClassificationOid(parentClassTreeVO.getOid().toString());
        parentProductSpectrumDTO.setName(parentClassTreeVO.getDisplayName());
        // 标记根节点为分类节点
        parentProductSpectrumDTO.setClassification(true);
        dealProductSpectrumChildren(parentClassTreeVO, parentProductSpectrumDTO, ibaAttr);
        return parentProductSpectrumDTO;
    }

    @Override
    public ProjectDevOrderDO queryProjectByNumber(BigInteger oid) {
        AttributeVO attributeVO = projectDevOrderMapper.selectPrjById(oid, RTPlmConstant.DEVORDER);
        if (ObjectUtil.isNull(attributeVO)) {
            throw RTErrorCodeEnum.PROJECT_DEV_ORDER.getException("项目编码为空");
        }
        String attributeValue = attributeVO.getAttributeValue();
        return projectDevOrderMapper.selectDevOrder(attributeValue);
    }

    @Override
    public List<ProjectDevOrderDO> queryByNumberAndName(String number, String projectName, String projectDevCode) {
        List<String> projectNameList = new ArrayList<>(Arrays.asList(projectName.split(" ")));
        List<String> projectDevCodeList = new ArrayList<>(Arrays.asList(projectDevCode.split(" ")));
        return projectDevOrderMapper.selectByNumberAndName(number, projectNameList, projectDevCodeList);

    }

    /**
     * 处理子型谱
     * @param parentClassTreeVO
     * @param parentProductSpectrumDTO
     * @param ibaAttr
     */
    private void dealProductSpectrumChildren(TyplmClassificationEntityTreeVO parentClassTreeVO,
                                             ProductSpectrumDTO parentProductSpectrumDTO, List<String> ibaAttr) {

        List<TyplmClassificationEntityTreeVO> children = parentClassTreeVO.getChildren();
        if (CollUtil.isNotEmpty(children)) {
            // 有子分类节点的情况 - 这些都是分类节点
            for (TyplmClassificationEntityTreeVO child : children) {
                List<ProductSpectrumDTO> list = parentProductSpectrumDTO.getList();
                ProductSpectrumDTO productSpectrumDTO = new ProductSpectrumDTO();
                productSpectrumDTO.setName(child.getDisplayName());
                // 设置分类OID
                productSpectrumDTO.setClassificationOid(child.getOid().toString());
                // 标记为分类节点
                productSpectrumDTO.setClassification(true);
                list.add(productSpectrumDTO);
                dealProductSpectrumChildren(child, productSpectrumDTO, ibaAttr);
            }
        } else {
            // 没有子分类节点的情况 - 这是叶子节点，需要添加物料信息
            String productLine = parentProductSpectrumDTO.getName().split("-")[0];
            parentProductSpectrumDTO.setProductLine(productLine);
            // 设置当前节点的分类OID
            parentProductSpectrumDTO.setClassificationOid(parentClassTreeVO.getOid().toString());
            // 标记为分类节点（虽然是叶子分类节点）
            parentProductSpectrumDTO.setClassification(true);

            List<ProductSpectrumDTO> list = parentProductSpectrumDTO.getList();
            SearchConditionDTO dto = new SearchConditionDTO();
            dto.setTypeInthid(TableTypeConstrant.TY_PART_OTYPE);
            dto.setClassificationOid(parentClassTreeVO.getOid());
            dto.setNeedThumbnailFile(false);
            dto.setPageSize(9999);
            dto.setPageNum(1);
            List<ResultEntityVO> resultEntityVOS = typlmClassifySearchService.queryByCondition(dto);
            List<BigInteger> partOidList = resultEntityVOS.stream().map(ResultEntityVO::getOid).collect(
                    Collectors.toList());
            List<List<BigInteger>> partOidListList = CommonUtil.subObjectList(partOidList, 800);
            Map<String, List<AttributeVO>> ibaMaps = new HashMap<>();
            for (List<BigInteger> ids : partOidListList) {
                Map<String, List<AttributeVO>> ibaMap = typlmAttributeValueService.getIbaAttrValueByOidAndKeys(
                        ids,
                        TableTypeConstrant.TY_PDMLINKPRODUCT_OTYPE,
                        ibaAttr);
                if(CollUtil.isNotEmpty(ibaMap)){
                    ibaMaps.putAll(ibaMap);
                }
            }

            for (String partOid : ibaMaps.keySet()) {
                ProductSpectrumDTO spectrumDTO = new ProductSpectrumDTO();
                List<AttributeVO> attrList = ibaMaps.get(partOid);
                if (CollUtil.isNotEmpty(attrList)) {
                    for (AttributeVO attributeVO : attrList) {
                        if ("devCode".equals(attributeVO.getAttributeEnName())) {
                            String devCode = StringUtils.isBlank(
                                    attributeVO.getAttributeValuex()) ? attributeVO.getAttributeValue()
                                    : attributeVO.getAttributeValuex();
                            spectrumDTO.setDevCode(devCode);
                        } else if ("productType".equals(attributeVO.getAttributeEnName())) {
                            String productType = StringUtils.isBlank(
                                    attributeVO.getAttributeValuex()) ? attributeVO.getAttributeValue()
                                    : attributeVO.getAttributeValuex();
                            spectrumDTO.setProductType(productType);
                        } else if ("ProductSeries".equals(attributeVO.getAttributeEnName())) {
                            String productCategory = StringUtils.isBlank(
                                    attributeVO.getAttributeValuex()) ? attributeVO.getAttributeValue()
                                    : attributeVO.getAttributeValuex();
                                    spectrumDTO.setProductCategory(productCategory);
                        }
                    }
                    if (StringUtils.isNotEmpty(spectrumDTO.getDevCode()) && StringUtils.isNotEmpty(
                            spectrumDTO.getProductType())) {
                        spectrumDTO.setName(spectrumDTO.getDevCode() + "-" + spectrumDTO.getProductType());
                        // 设置零件节点的分类OID（来自父节点）
                        spectrumDTO.setClassificationOid(parentClassTreeVO.getOid().toString());
                        // 标记为物料节点
                        spectrumDTO.setClassification(false);
                        list.add(spectrumDTO);
                    }
                }
            }
        }
    }

    @Override
    public String queryModelByDevCode(String devCode) {
        List<String> data = projectDevOrderMapper.selectModelByDevCode(devCode);
        if(CollUtil.isEmpty(data)){
            return "";
        }else {
            return data.get(0);
        }
    }

    @Override
    public String querySeriesByDevCode(String name) {
        return projectDevOrderMapper.querySeriesByDevCode(name);
    }
}

